/// <reference path="../libs/Cesium/Cesium.js" />

let ScaleControl = (function () {

    /**
     * 比例尺控件
     * @param {*} element 容器元素
     * @param {*} viewer Viewer
     */
    function ScaleControl(element, viewer) {
        this.container = $(element);
        this.viewer = viewer;

        this.scaleGraph = undefined;
        this.scaleMsg = undefined;
        this.scaleGraphWidth = undefined;

        this.container.attr("class", "scale-container");
        this.container.html('<div class="scale-msg"></div><div class="scale-graph"></div>');

        this.viewer.scene.camera.moveEnd.addEventListener(e => {
            this.show();
        });

        // 首次展示 
        (async () => {
            while (await this.check() < 100) { }
            this.show();
        })();
    }

    ScaleControl.prototype.check = function () {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (!this.checkCount) this.checkCount = 0;
                this.checkCount++;
                let height = $(window).height();
                let width = $(window).width();
                let pick1 = new Cesium.Cartesian2(width / 2, height / 2);
                let pick2 = new Cesium.Cartesian2(width / 2 + 100, height / 2);
                let cartesian1 = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(pick1), this.viewer.scene);
                let cartesian2 = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(pick2), this.viewer.scene);
                if (cartesian1 && cartesian2) {
                    resolve(999);
                } else {
                    resolve(this.checkCount);
                }
            }, 100);
        });
    }

    //显示比例尺
    ScaleControl.prototype.show = function () {
        let height = $(window).height();
        let width = $(window).width();
        if (!this.scaleMsg) this.scaleMsg = this.container.find(".scale-msg");
        if (!this.scaleGraph) this.scaleGraph = this.container.find(".scale-graph");
        if (!this.scaleGraphWidth) this.scaleGraphWidth = this.scaleGraph.width();

        let pick1 = new Cesium.Cartesian2(width / 2, height / 2);
        let pick2 = new Cesium.Cartesian2(width / 2 + 100, height / 2);
        let cartesian1 = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(pick1), this.viewer.scene);
        let cartesian2 = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(pick2), this.viewer.scene);
        if (cartesian1 && cartesian2) {
            let cartographic1 = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian1);
            let cartographic2 = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian2);
            let lng1 = Cesium.Math.toDegrees(cartographic1.longitude);
            let lat1 = Cesium.Math.toDegrees(cartographic1.latitude);
            let lng2 = Cesium.Math.toDegrees(cartographic2.longitude);
            let lat2 = Cesium.Math.toDegrees(cartographic2.latitude);

            let from = turf.point([lng1, lat1]);
            let to = turf.point([lng2, lat2]);
            let options = { units: 'kilometers' };

            let distance = turf.distance(from, to, options);

            if (distance > 1) {
                let d = this.getDistanceKm(distance);
                let ratio = d / distance;
                let width = ratio * this.scaleGraphWidth;
                this.scaleGraph.css("width", width + "px");
                this.scaleMsg.html(d + " km");
            } else {
                distance = distance * 1000;
                let d = this.getDistanceM(distance);
                let ratio = d / distance;
                let width = ratio * this.scaleGraphWidth;
                this.scaleGraph.css("width", width + "px");
                this.scaleMsg.html(d + " m");
            }
        }
    };

    //distance转换
    ScaleControl.prototype.getDistanceKm = function (distance) {
        let arr = [1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500, 1000, 2000, 3000, 5000];

        for (let i = 0; i < arr.length - 1; i++) {
            if (distance >= arr[i] && distance <= arr[i + 1]) {
                return arr[i];
            }
        }

        if (distance < arr[0]) {
            return arr[0];
        }

        if (distance > arr[arr.length - 1]) {
            return arr[arr.length - 1];
        }
    }

    //distance转换
    ScaleControl.prototype.getDistanceM = function (distance) {
        let arr = [10, 20, 30, 50, 100, 200, 300, 500];

        for (let i = 0; i < arr.length - 1; i++) {
            if (distance >= arr[i] && distance <= arr[i + 1]) {
                return arr[i];
            }
        }

        if (distance < arr[0]) {
            return arr[0];
        }

        if (distance > arr[arr.length - 1]) {
            return arr[arr.length - 1];
        }
    }

    return ScaleControl;
})();
